﻿using JWT.Algorithms;
using JWT.Serializers;
using JWT;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using System.Security.Claims;
using System.Text;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using System.Security.Cryptography;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Security.Cryptography.X509Certificates;

namespace XxSystem.FileManager.core
{
    public class JWTHelper
    {

        private static string _secret = "trastehnare123sth2lu13pnersh189prm,,.tarst12";
        private static string cerateJwtToken(IDictionary<string, string> data, string secret)
        {
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            var token = encoder.Encode(data, secret);
            return token;
        }
        private static string validateJwtToken(string token, string secret)
        {
            try
            {
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder encoder = new JwtBase64UrlEncoder();
                IJwtAlgorithm alg = new HMACSHA256Algorithm();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, encoder, alg);
                var json = decoder.Decode(token, secret, true);
                return json;

            }
            catch (Exception ex)
            {
                throw new Exception("验证失败");
            }
        }

        public static string CreateToken(IDictionary<string, string> data) 
        { 
            return cerateJwtToken(data, _secret);
        }
        public static string validateToken(string token)
        { 
            return validateJwtToken(token, _secret);
        }
        /// <summary>
        /// 生成token
        /// </summary>
        /// <returns></returns>
        public static string GetJwtToken(IDictionary<string, string> data)
        {
            //对称秘钥
            SecurityKey securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_secret));

            var claims = new List<Claim>();
            foreach (var claim in data) 
            { 
                claims.Add(new Claim(claim.Key, claim.Value));
            }
            JwtSecurityToken jwtToken = new JwtSecurityToken(
                issuer: "fan",
                audience: "fan",
                claims: claims,
                notBefore: DateTime.UtcNow,
                expires: DateTime.UtcNow.AddDays(1),
                signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256)
                );

            //生成token方式1
            string token = new JwtSecurityTokenHandler().WriteToken(jwtToken);

            ////生成token方式2
            //var tokenDescriptor = new SecurityTokenDescriptor // 创建一个 Token 的原始对象
            //{
            //    Issuer = "fan",
            //    Audience = "fan",
            //    Subject = new ClaimsIdentity(new[]
            //           {
            //                new Claim(ClaimTypes.Name, "")
            //            }),
            //    Expires = DateTime.Now.AddMinutes(60),
            //    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(key)), SecurityAlgorithms.HmacSha256)
            //};
            //SecurityToken securityToken = new JwtSecurityTokenHandler().CreateToken(tokenDescriptor);
            //var token2 = new JwtSecurityTokenHandler().WriteToken(securityToken);

            return token;
        }
        /// <summary>
        /// 校验token
        /// </summary>
        /// <param name="token"></param>
        /// <param name="principal"></param>
        /// <returns></returns>
        public static bool VerifyJwtToken(string token, out ClaimsPrincipal principal)
        {
            principal = null;
            //对称秘钥
            SecurityKey securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_secret));
            //校验token
            var validateParameter = new TokenValidationParameters()
            {
                ValidateLifetime = true,
                ValidateAudience = true,
                ValidateIssuer = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = "fan",
                ValidAudience = "fan",
                IssuerSigningKey = securityKey,
                ClockSkew = TimeSpan.Zero//校验过期时间必须加此属性
            };
            //不校验，直接解析token
            //jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token1);
            bool success = false;
            try
            {
                //校验并解析token,validatedToken是解密后的对象
                principal = new JwtSecurityTokenHandler().ValidateToken(token, validateParameter, out SecurityToken validatedToken);
                //获取payload中的数据 
                //var jwtPayload = ((JwtSecurityToken)validatedToken).Payload.SerializeToJson(); 
                success = true;

            }
            catch (SecurityTokenExpiredException ex)
            {
                //表示过期
                success = false;
            }
            catch (SecurityTokenException ex)
            {
                //表示token错误
                success = false;
            }
            catch (Exception ex)
            {
                success = false;
            }
            return success;
        }

     
    }
}

